package com.zxl.manager.privacy.utils.utils;

import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.PaintFlagsDrawFilter;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Typeface;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.Drawable;

/**
 * <br>类描述: 气球的参数
 * <br>功能详细描述:
 * 
 * @author  yangxijun
 * @date  [2015年6月4日]
 */
public class BalloonParams {
	
	/**
	 * 初始的x值
	 */
	public float mStartX;
	/**
	 * 初始的y值
	 */
	public float mStartY;
	/**
	 * 球的x轴速度
	 */
	public float mVx;
	/**
	 * 球的y轴速度
	 */
	public float mVy;
	/**
	 * 球的加速度
	 */
	public float mAccerator;

	public BalloonParams(float startX, float startY, float vx, float vy, float accerator) {
		mStartX = startX;
		mStartY = startY;
		mVx = vx;
		mVy = vy;
		mAccerator = accerator;
	}

	// =================  公用  ==================================
	private static Canvas sCanvas = null;
	private static Paint sPaint = null;
	private static int sCanvasOriCount;
	private static Rect sRect = new Rect();

	public static Canvas obtainCanvas() {
		if (sCanvas == null) {
			sCanvas = new Canvas();
			sCanvasOriCount = sCanvas.getSaveCount();
			sCanvas.setDrawFilter(new PaintFlagsDrawFilter(0, Paint.ANTI_ALIAS_FLAG
					| Paint.FILTER_BITMAP_FLAG));
		}
		if (sCanvasOriCount != sCanvas.getSaveCount()) {
			sCanvas.restoreToCount(sCanvasOriCount);
		}
		return sCanvas;
	}

	public static Paint obtainPaint() {
		if (sPaint == null) {
			sPaint = new Paint();
		}
		sPaint.reset();
		sPaint.setAntiAlias(true);
		sPaint.setFilterBitmap(true);
		return sPaint;
	}

	/** <br>功能简述: 生成试试手气的刷新气球
	 * <br>功能详细描述:
	 * <br>注意:
	 * @param balloon
	 * @param star
	 * @return
	 */
	public static Bitmap createShuffleBalloon(Drawable balloon, Drawable star) {
		Bitmap dst = Bitmap.createBitmap(balloon.getIntrinsicWidth(),
				balloon.getIntrinsicHeight() + star.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(dst);
		Paint paint = obtainPaint();
		int offset = -DrawUtils.dip2px(1);
		canvas.drawBitmap(((BitmapDrawable) balloon).getBitmap(), 0, 0, paint);
		canvas.drawBitmap(((BitmapDrawable) star).getBitmap(), offset, balloon.getIntrinsicHeight() + offset, paint);
		return dst;
	}

	/** <br>功能简述: 画出圆角图片
	 * <br>功能详细描述:
	 * <br>注意:
	 * @param source
	 * @param width
	 * @param height
	 * @param radius
	 * @return
	 */
	public static Bitmap createUpperRoundCornerImage(Bitmap source, int width,
													 int height, int radius) {
		Paint paint = new Paint();
		paint.setAntiAlias(true);
		Bitmap target = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(target);

		// 向下一个圆角半径的长度, 这样下边界就不会有圆角
		RectF rect = new RectF(0, 0, source.getWidth(), source.getHeight()
				+ radius);
		canvas.drawRoundRect(rect, radius, radius, paint);
		paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
		canvas.drawBitmap(source, 0, 0, paint);
		return target;
	}

	/**
	 * 绘制左下，右上圆角的特殊圆角矩形
	 * */
	private static final int ROUND_RECT_WIDTH = DrawUtils.dip2px(46);
	private static final int ROUND_RECT_HEIGHT = DrawUtils.dip2px(14);
	private static final int ROUND_RADIUS = DrawUtils.dip2px(3);
	private static final int ROUND_BACK_COLOR = 0x66000000;
	private static final int ROUND_TEXT_SIZE = DrawUtils.px2dip(8);
	private static final int ROUND_TEXT_SHADOW_SIZE = DrawUtils.dip2px(1);
	private static final int ROUND_TEXT_SHADOW_DISTANCE = DrawUtils.dip2px(1);
	private static final int ROUND_TEXT_SHADOW_COLOR = 0xffb3f012;
	private static final int TEXT_COLOR = 0xffb3f012;

	public static Bitmap createSpecialRoundRect(boolean upLeft, boolean upRight, boolean bottomRight, boolean bottomLeft) {
		Bitmap bmp = Bitmap.createBitmap(ROUND_RECT_WIDTH, ROUND_RECT_HEIGHT, Bitmap.Config.ARGB_8888);
		Paint p = obtainPaint();
		p.setColor(ROUND_BACK_COLOR);
		p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
		Canvas c = obtainCanvas();
		c.setBitmap(bmp);
		// 先画一个正常圆角矩形
		RectF normalR = new RectF(0, 0, ROUND_RECT_WIDTH, ROUND_RECT_HEIGHT);
		c.drawRoundRect(normalR, ROUND_RADIUS, ROUND_RADIUS, p);
		// 再画两个略大于圆角的矩形，覆盖掉左上和右下两个角
		final int coverRectSize = ROUND_RADIUS + DrawUtils.dip2px(1); // 覆盖的矩形略大于圆角
		if (!upLeft) {
			RectF rectLeftTop = new RectF(0, 0, coverRectSize, coverRectSize);
			c.drawRect(rectLeftTop, p);
		}
		if (!upRight) {
			RectF rectLeftTop = new RectF(ROUND_RECT_WIDTH - coverRectSize, 0, ROUND_RECT_WIDTH, coverRectSize);
			c.drawRect(rectLeftTop, p);
		}
		if (!bottomLeft) {
			RectF rectLeftTop = new RectF(0, ROUND_RECT_HEIGHT - coverRectSize, coverRectSize, ROUND_RECT_HEIGHT);
			c.drawRect(rectLeftTop, p);
		}
		if (!bottomRight) {
			RectF rectRightBottom = new RectF(ROUND_RECT_WIDTH - coverRectSize, ROUND_RECT_HEIGHT - coverRectSize, ROUND_RECT_WIDTH, ROUND_RECT_HEIGHT);
			c.drawRect(rectRightBottom, p);
		}

		// 最后画上字母
		Paint textPaint = obtainPaint();
		textPaint.setColor(Color.WHITE);
		textPaint.setTextSize(ROUND_TEXT_SIZE);
		textPaint.setTextAlign(Paint.Align.CENTER);
		textPaint.setTypeface(Typeface.DEFAULT_BOLD);
		Paint.FontMetricsInt textMetrics = textPaint.getFontMetricsInt();
		textPaint.setColor(TEXT_COLOR);
		// textPaint.setShadowLayer(ROUND_TEXT_SHADOW_SIZE, 0,
		// ROUND_TEXT_SHADOW_DISTANCE, ROUND_TEXT_SHADOW_COLOR);
		c.drawText("推荐", ROUND_RECT_WIDTH / 2, (ROUND_RECT_HEIGHT - textMetrics.bottom + textMetrics.top) / 2 - textMetrics.top, textPaint);

		return bmp;
	}

	/**
	 * <br>
	 * 功能简述: 将广告标志画在图片右上角 <br>
	 * 功能详细描述: <br>
	 * 注意:
	 *
	 * @param src
	 * @return
	 */
	public static Bitmap getADBitmap(Bitmap src) {
		Bitmap dst = Bitmap.createBitmap(src.getWidth(), src.getHeight(), Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(dst);
		Paint paint = BalloonParams.obtainPaint();
		Bitmap adBitmap = BalloonParams.createSpecialRoundRect(false, true, false, true);
		canvas.drawBitmap(src, 0, 0, paint);
		canvas.drawBitmap(adBitmap, src.getWidth() - adBitmap.getWidth(), 0, paint);
		return dst;
	}

	/**
	 * 功能简述: 绘制带有遮罩的图 功能详细描述: 注意:
	 *
	 * @param src
	 * @param color
	 * @return
	 */
	public static Bitmap getMaskBitmap(Bitmap src, int color) {
		int width = src.getWidth();
		int height = src.getHeight();
		Bitmap dst = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
		Canvas canvas = new Canvas(dst);
		Paint paint = BalloonParams.obtainPaint();
		canvas.drawBitmap(src, 0, 0, paint);
		canvas.drawColor(color);

		return dst;
	}

	/**
	 * 功能简述: 模糊并生成图片
	 * 功能详细描述:
	 * 注意:
	 * @param bkg 要模糊的原图
	 * @param blurWidthScale 要模糊的区域宽度占原图的比例
	 * @param blurHeightScale 要模糊的区域高度占原图的比例
	 * @param leftScale 模糊区域左上角占原图的比例
	 * @param topScale 模糊区域左上角占原图的比例
	 * @param radius 模糊的半径
	 * @return 模糊后的bitmap
	 */
	public static Bitmap blur(Bitmap bkg, float blurWidthScale, float blurHeightScale, float leftScale, float topScale,
							  int radius) {
		float scaleFactor = 8; // 为了缩小时间，先缩小8倍进行模糊

		int blurWidth = (int) (bkg.getWidth() * blurWidthScale);
		int blurHeight = (int) (bkg.getHeight() * blurHeightScale);
		float left = bkg.getWidth() * leftScale;
		float top = bkg.getHeight() * topScale;

		int overlayWidth = (int) (blurWidth / scaleFactor);
		int overlayHeight = (int) (blurHeight / scaleFactor);
		if (overlayWidth > 0 && overlayHeight > 0) {
			Bitmap overlay = Bitmap.createBitmap(overlayWidth, overlayHeight, Bitmap.Config.ARGB_8888);
			Canvas canvas = new Canvas(overlay);
			canvas.translate(-left / scaleFactor, -top / scaleFactor);
			canvas.scale(1 / scaleFactor, 1 / scaleFactor);
			Paint paint = new Paint();
			paint.setFlags(Paint.FILTER_BITMAP_FLAG);
			canvas.drawBitmap(bkg, 0, 0, paint);

			overlay = blur(overlay, radius, true);
			return zoomBitmap(overlay, blurWidth, blurHeight);
		} else {
			return null;
		}
	}

	/**
	 * <br>功能简述: 模糊效果
	 * <br>功能详细描述:
	 * <br>注意:
	 * @param sentBitmap
	 * @param radius 模糊半径，调效果
	 * @param canReuseInBitmap 是否作用在sentBitmap
	 * @return
	 */
	private static Bitmap blur(Bitmap sentBitmap, int radius, boolean canReuseInBitmap) {
		// Stack Blur v1.0 from
		// http://www.quasimondo.com/StackBlurForCanvas/StackBlurDemo.html
		//
		// Java Author: Mario Klingemann <mario at quasimondo.com>
		// http://incubator.quasimondo.com
		// created Feburary 29, 2004
		// Android port : Yahel Bouaziz <yahel at kayenko.com>
		// http://www.kayenko.com
		// ported april 5th, 2012
		// This is a compromise between Gaussian Blur and Box blur
		// It creates much better looking blurs than Box Blur, but is
		// 7x faster than my Gaussian Blur implementation.
		//
		// I called it Stack Blur because this describes best how this
		// filter works internally: it creates a kind of moving stack
		// of colors whilst scanning through the image. Thereby it
		// just has to add one new block of color to the right side
		// of the stack and remove the leftmost color. The remaining
		// colors on the topmost layer of the stack are either added on
		// or reduced by one, depending on if they are on the right or
		// on the left side of the stack.
		//
		// If you are using this algorithm in your code please add
		// the following line:
		//
		// Stack Blur Algorithm by Mario Klingemann <mario@quasimondo.com>
		Bitmap bitmap;
		if (canReuseInBitmap) {
			bitmap = sentBitmap;
		} else {
			bitmap = sentBitmap.copy(sentBitmap.getConfig(), true);
		}
		if (radius < 1) {
			return null;
		}
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		int[] pix = new int[w * h];
		bitmap.getPixels(pix, 0, w, 0, 0, w, h);
		int wm = w - 1;
		int hm = h - 1;
		int wh = w * h;
		int div = radius + radius + 1;
		int r[] = new int[wh];
		int g[] = new int[wh];
		int b[] = new int[wh];
		int rsum, gsum, bsum, x, y, i, p, yp, yi, yw;
		int vmin[] = new int[Math.max(w, h)];
		int divsum = (div + 1) >> 1;
		divsum *= divsum;
		int dv[] = new int[256 * divsum];
		for (i = 0; i < 256 * divsum; i++) {
			dv[i] = i / divsum;
		}
		yw = yi = 0;
		int[][] stack = new int[div][3];
		int stackpointer;
		int stackstart;
		int[] sir;
		int rbs;
		int r1 = radius + 1;
		int routsum, goutsum, boutsum;
		int rinsum, ginsum, binsum;
		for (y = 0; y < h; y++) {
			rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
			for (i = -radius; i <= radius; i++) {
				p = pix[yi + Math.min(wm, Math.max(i, 0))];
				sir = stack[i + radius];
				sir[0] = (p & 0xff0000) >> 16;
				sir[1] = (p & 0x00ff00) >> 8;
				sir[2] = p & 0x0000ff;
				rbs = r1 - Math.abs(i);
				rsum += sir[0] * rbs;
				gsum += sir[1] * rbs;
				bsum += sir[2] * rbs;
				if (i > 0) {
					rinsum += sir[0];
					ginsum += sir[1];
					binsum += sir[2];
				} else {
					routsum += sir[0];
					goutsum += sir[1];
					boutsum += sir[2];
				}
			}
			stackpointer = radius;
			for (x = 0; x < w; x++) {
				r[yi] = dv[rsum];
				g[yi] = dv[gsum];
				b[yi] = dv[bsum];
				rsum -= routsum;
				gsum -= goutsum;
				bsum -= boutsum;
				stackstart = stackpointer - radius + div;
				sir = stack[stackstart % div];
				routsum -= sir[0];
				goutsum -= sir[1];
				boutsum -= sir[2];
				if (y == 0) {
					vmin[x] = Math.min(x + radius + 1, wm);
				}
				p = pix[yw + vmin[x]];
				sir[0] = (p & 0xff0000) >> 16;
				sir[1] = (p & 0x00ff00) >> 8;
				sir[2] = p & 0x0000ff;
				rinsum += sir[0];
				ginsum += sir[1];
				binsum += sir[2];
				rsum += rinsum;
				gsum += ginsum;
				bsum += binsum;
				stackpointer = (stackpointer + 1) % div;
				sir = stack[stackpointer % div];
				routsum += sir[0];
				goutsum += sir[1];
				boutsum += sir[2];
				rinsum -= sir[0];
				ginsum -= sir[1];
				binsum -= sir[2];
				yi++;
			}
			yw += w;
		}
		for (x = 0; x < w; x++) {
			rinsum = ginsum = binsum = routsum = goutsum = boutsum = rsum = gsum = bsum = 0;
			yp = -radius * w;
			for (i = -radius; i <= radius; i++) {
				yi = Math.max(0, yp) + x;
				sir = stack[i + radius];
				sir[0] = r[yi];
				sir[1] = g[yi];
				sir[2] = b[yi];
				rbs = r1 - Math.abs(i);
				rsum += r[yi] * rbs;
				gsum += g[yi] * rbs;
				bsum += b[yi] * rbs;
				if (i > 0) {
					rinsum += sir[0];
					ginsum += sir[1];
					binsum += sir[2];
				} else {
					routsum += sir[0];
					goutsum += sir[1];
					boutsum += sir[2];
				}
				if (i < hm) {
					yp += w;
				}
			}
			yi = x;
			stackpointer = radius;
			for (y = 0; y < h; y++) {
				// Preserve alpha channel: ( 0xff000000 & pix[yi] )
				pix[yi] = (0xff000000 & pix[yi]) | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum];
				rsum -= routsum;
				gsum -= goutsum;
				bsum -= boutsum;
				stackstart = stackpointer - radius + div;
				sir = stack[stackstart % div];
				routsum -= sir[0];
				goutsum -= sir[1];
				boutsum -= sir[2];
				if (x == 0) {
					vmin[y] = Math.min(y + r1, hm) * w;
				}
				p = x + vmin[y];
				sir[0] = r[p];
				sir[1] = g[p];
				sir[2] = b[p];
				rinsum += sir[0];
				ginsum += sir[1];
				binsum += sir[2];
				rsum += rinsum;
				gsum += ginsum;
				bsum += binsum;
				stackpointer = (stackpointer + 1) % div;
				sir = stack[stackpointer];
				routsum += sir[0];
				goutsum += sir[1];
				boutsum += sir[2];
				rinsum -= sir[0];
				ginsum -= sir[1];
				binsum -= sir[2];
				yi += w;
			}
		}
		bitmap.setPixels(pix, 0, w, 0, 0, w, h);
		return bitmap;
	}

	/**
	 * 通过传入的大小返回对应的图片(缩放/剪切等操作)
	 * @param bitmap 要缩放的图片
	 * @return
	 */
	public static Bitmap zoomBitmap(Bitmap bitmap, int newWidth, int newHeight) {
		if (bitmap == null) {
			return bitmap;
		}
		//获取Bitmap宽度
		int width = bitmap.getWidth();
		//获取Bitmap高度
		int height = bitmap.getHeight();
		if (width == newWidth && height == newHeight) {
			return bitmap;
		}
		Matrix matrix = new Matrix();
		//参考Bitmap高度获取缩放比例(高度)
		float scale = newHeight / (float) height;
		//如果缩放出来的宽度少于需要的宽度,则参照宽度比例缩放Bitmap.
		if (width * scale < newWidth) {
			scale = newWidth / (float) width;
		}
		//设置缩放比例
		matrix.postScale(scale, scale);
		if (width * scale - newWidth > 0 || height * scale - newHeight > 0) {
			// 缩放并截取图片
			return Bitmap.createBitmap(Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true), width * scale - newWidth > 0 ? (int) (width * scale - newWidth) / 2 : 0, height * scale - newHeight > 0 ? (int) (height * scale - newHeight) / 2 : 0, newWidth, newHeight);
		}
		//缩放图片
		return Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true);
	}

}
